package bancosys.tec.persist.span.fat;

import java.util.Collection;
import java.util.List;

import bancosys.tec.persist.span.SpanAwareBean;
import bancosys.tec.utils.date.Date;

/**
 * Classe helper para lidar com vigencias
 * 
 * @author takeshi
 */
public final class FatSpanAwareHelper {

    /**
     * C'tor
     */
    private FatSpanAwareHelper() {
    }

    /**
     * Devolve a vigência atual, ou seja, a vigência que possui a data atual dentro do seu período.
     * 
     * @param fatBean BO pai das vigências.
     * @return vigência atual.
     * @param <T> Tipo da vigencia
     */
    public static <T extends SpanAwareBean> T getVigenciaAtual(FatSpanAwareBean<T> fatBean) {
        return getVigenciaByPeriod(fatBean.getVigencias(), new Date());
    }

    /**
     * Devolve a ultima vigência de um FatSpanAwareBean. <br>
     * Utiliza a dataInicio, das vigências, para descobrir qual é a última.
     * 
     * @param <T> BO da vigência.
     * @param fatBean BO pai das vigências.
     * @return ultima vigência.
     */
    public static <T extends SpanAwareBean> T getUltimaVigencia(FatSpanAwareBean<T> fatBean) {
        T ultimaVigencia = null;
        List<T> beans = fatBean.getVigencias();
        Date dataInicioMax = null;

        if (beans != null) {
            for (T bean : beans) {
                if (bean.getDataInicio() != null && dataInicioMax == null) {
                    dataInicioMax = bean.getDataInicio();
                }

                if (bean.getDataInicio() != null && dataInicioMax != null && !dataInicioMax.after(bean.getDataInicio())) {
                    ultimaVigencia = bean;
                    dataInicioMax = bean.getDataInicio();
                }
            }
        }
        return ultimaVigencia;
    }

    /**
     * Devolve a primeira vigência encontrada com dataFim igual a 31/12/9999.
     * 
     * @deprecated Utilize o método <code>FatSpanAwareHelper.getVigenciaAtual(FatSpanAwareBean)}</code>.
     * @param <T> BO de vigência.
     * @param beans lista com as vigências.
     * @return primeira vigência encontrada com dataFim igual a 31/12/9999.
     */
    @Deprecated
    public static <T extends SpanAwareBean> T getVigenciaAtual(Collection<T> beans) {
        T vigenciaAtual = null;

        if (beans != null) {
            for (T bean : beans) {
                if (bean.getDataFim() != null && bean.getDataFim().equals(SpanAwareBean.DATA_FIM)) {
                    vigenciaAtual = bean;
                }
            }
        }
        return vigenciaAtual;
    }

    /**
     * Busca uma vigência, dentro de uma coleção de vigências, de acordo com a dataFim passada.
     * 
     * @param <T> BO de vigência.
     * @param beans lista com as vigências.
     * @param data data fim que será utilizada na busca.
     * @return vigência com dataFim correspondente a data passada.
     */
    public static <T extends SpanAwareBean> T getVigenciaByDataFim(Collection<T> beans, Date data) {
        T vigencia = null;

        if (beans != null) {
            for (T bean : beans) {
                if (bean.getDataFim() != null && bean.getDataFim().equals(data)) {
                    vigencia = bean;
                }
            }
        }
        return vigencia;
    }

    /**
     * Obter vigencia dentro de um periodo.
     * 
     * @param <T> BO de Vigencia.
     * @param beans Collection de vigencia.
     * @param data A data a ser comparada dentro do período.
     * @return vigência que possui a data passada dentro do seu período.
     */
    public static <T extends SpanAwareBean> T getVigenciaByPeriod(Collection<T> beans, Date data) {
        T vigencia = null;

        if (beans != null) {
            for (T bean : beans) {
                Date dataInicio = bean.getDataInicio();
                Date dataFim = bean.getDataFim();
                if (data.after(dataInicio) && data.before(dataFim) || data.equals(dataInicio) || data.equals(dataFim)) {
                    vigencia = bean;
                    break;
                }
            }
        }
        return vigencia;
    }

    /**
     * Busca uma vigência, dentro de um FatSpanAwareBean, de acordo com a dataFim passada.
     * 
     * @param fatBean BO pai das vigências.
     * @param dataFim data fim que será utilizada na busca.
     * @return vigência com dataFim correspondente a data passada.
     * @param <T> Tipo da vigencia
     */
    public static <T extends SpanAwareBean> T getVigenciaByDataFim(FatSpanAwareBean<T> fatBean, Date dataFim) {
        return getVigenciaByDataFim(fatBean.getVigencias(), dataFim);
    }
}
